#pragma once

#include "fxcc/core/graph/common/Effect3d.h"
#include "fxcc/core/graph/common/Geometry.h"
#include "fxcc/core/graph/common/GlslShader.h"
#include "fxcc/core/graph/common/Defines.h"
#include "fxcc/core/graph/common/EffectsDesc.h"

#include "fxcc/core/graph/opengl3/RenderStates.h"
#include "fxcc/core/graph/opengl3/UniformBuffer.h"
#include "fxcc/core/graph/opengl3/Shader.h"
#include "fxcc/core/graph/opengl3/MeshJack.h"
#include "fxcc/core/graph/opengl3/Texture2DJack.h"
#include "mustache.hpp"

namespace fxcc
{
	namespace graph
	{
		namespace opengl3
		{
			struct FXCC_API Effect3d :public fxcc::graph::common::Effect3d
			{
				std::shared_ptr<fxcc::graph::opengl3::Shader> m_Shader, m_AnimShader;

				std::shared_ptr<fxcc::graph::opengl3::Shader> m_CurrentShader;

				std::shared_ptr<fxcc::graph::common::GlslShader> m_ShaderLang;

				fxcc::graph::common::EffectDesc m_EffectDesc;

				Effect3d(const fxcc::graph::common::EffectDesc& effectDesc);

				Effect3d(const std::string& fragMain, const fxcc::graph::common::Defines defines = {});

				Effect3d(const ShaderDesc& shaderDesc, const fxcc::graph::common::Defines defines = {});

				void Influence(fxcc::graph::common::MaterialView& material);

				void UseMaterial(const fxcc::graph::common::MaterialView& material);

				void Init();

				void SetFixed();

				void SetSkinned();

				void Begin();

				static void SetObjData(const ObjData& objData);

				static void SetObjData(const fxcc::graph::common::Transform& tranform);

				static void SetBoneData(const BoneData& boneData);

				static std::shared_ptr<fxcc::graph::opengl3::IBuffers> GetBuffers();

				static void SetLightEffect(const fxcc::graph::common::LightEffect& lightEffect);

				static void SetCamera(const fxcc::graph::common::Camera& camera);

				static void SetCamera(const fxcc::graph::common::OrthoCamera& camera);

				static void SetPassData(const fxcc::graph::common::Effect3d::PassData& passData);

				static void SetTransform(const fxcc::graph::common::Transform& transform);

				static void GetTexture2DJackBufferData(const fxcc::graph::common::ImageMipmap::MipMapData& textureInfo, PassData& passData, ObjData& objData);

				static void GetTexture2DJackBufferData(int width, int height, PassData& passData, ObjData& objData);

				void InstQuad();

				void InstQuad2();

				void InstMeshJack(const fxcc::graph::opengl3::MeshJack* mesh);

				void InstSkinnedMeshJack(const fxcc::graph::opengl3::MeshJack* mesh);

				void End();

				static void Viewport(int x, int y, int w, int h);

				static void ClearBgColor(const glm::vec4&);

				static void ClearBuffer(bool color, bool depthStencil);

				ShaderDesc m_SimpleShaderDesc;

				ShaderDesc m_AnimShaderDesc;

				ShaderDesc m_FixedShaderDesc;

				std::string GetFragCode();

				std::string GetTCSCode();

				std::string GetTESCode();

				static const std::string GetVertCode();

				static const std::string GetVertAnimCode();

				static const std::string GetVertTemp();

				static const std::string GetFragCodeTemp();

				static fxcc::graph::common::Defines GetSkinnedDefine();


			};
		};

	};
}